home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2010 April
/
PCWorld0410.iso
/
pluginy Firefox
/
52856
/
52856.xpi
/
chrome
/
content
/
handytab.js
< prev
next >
Wrap
Text File
|
2009-12-03
|
15KB
|
426 lines
Components.utils.import("resource://handytab/datastore.jsm");
const FENNEC_APP_ID = "{a23983c0-fd0e-11dc-95ff-0800200c9a66}"
var handytab = {
mobileMode: false,
prefs: null,
homepage: "chrome://handytab/locale/handytab.html",
autosave: false,
markKey: 'x',
invertKey: 'z',
markKeyDown: false,
invertKeyDown: false,
markMode: false,
prefListener : {
register: function() {
var branch = handytab.prefs.QueryInterface(Components.interfaces.nsIPrefBranch2);
branch.addObserver("", this, false);
},
observe: function(subject, topic, data) {
if (topic != "nsPref:changed") return;
switch (data) {
case "show.closebtn":
var tab = handytab.findTab(false, false);
if (tab) handytab.updateCloseButton(tab);
break;
case "homepage":
handytab.homepage = handytab.prefs.getCharPref("homepage");
break;
case "mark.key":
handytab.markKey = handytab.prefs.getCharPref("mark.key");
break;
}
}
},
sendMarksToHtml: function(doc, all) {
var element = doc.getElementById("handytab-api");
var marks = HandyTabDataStore.getMarks(all);
element.setAttribute("data", marks);
var evt = doc.createEvent("Events");
evt.initEvent("HandyTabHtmlEvent", true, false);
element.dispatchEvent(evt);
},
onHandyTabAddonEvent: function(e) {
if (e.target.ownerDocument.location != this.homepage) return;
var subject = e.target.getAttribute("subject");
switch (subject) {
case "fetch-rows":
this.sendMarksToHtml(e.target.ownerDocument, true);
break;
case "remove-rows":
var args = e.target.getAttribute("args");
HandyTabDataStore.removeMarks(args);
break;
}
},
log: function(msg) {
var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService);
consoleService.logStringMessage('handytab: ' + msg);
},
catchLinkClick: function() {
var tab = this.mobileMode ? Browser.selectedTab.chromeTab : gBrowser.selectedTab;
if (tab.hasAttribute("handytab-hooked")) return;
tab.setAttribute("handytab-hooked", "true");
var browser = this.mobileMode ? Browser.selectedBrowser : gBrowser.getBrowserForTab(tab);
browser.addEventListener("keydown", function(e) {
var key = String.fromCharCode(e.which).toLowerCase();
if (handytab.markKey.toLowerCase() == key) {
handytab.markKeyDown = true;
}
else if (handytab.invertKey.toLowerCase() == key) {
handytab.invertKeyDown = true;
}
}, false);
browser.addEventListener("keyup", function(e) {
var key = String.fromCharCode(e.which).toLowerCase();
if (handytab.markKey.toLowerCase() == key) {
handytab.markKeyDown = false;
}
else if (handytab.invertKey.toLowerCase() == key) {
handytab.invertKeyDown = false;
}
}, false);
browser.addEventListener("click", function(e) {
if (e.button != 0 || e.ctrlKey || e.altKey || e.shiftKey) return;
if (e.target.tagName == "A" || e.target.tagName == "IMG" || e.target.parentNode.tagName == "A") {
if (((handytab.markMode && !handytab.invertKeyDown) || (!handytab.markMode && handytab.invertKeyDown)) &&
e.target.ownerDocument.location.toString() != handytab.homepage) {
handytab.addMark(e.target);
e.preventDefault();
e.stopPropagation();
}
} else if (handytab.markKeyDown) {
handytab.toogleMarkMode();
}
}, true);
},
onLoad: function() {
this.initialized = true;
this.strings = document.getElementById("handytab-strings");
var info = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULAppInfo);
if (info.ID == FENNEC_APP_ID) this.mobileMode = true;
var prefSrv = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
this.prefs = prefSrv.getBranch("extensions.handytab.options.");
this.prefListener.register();
HandyTabDataStore.init();
this.autosave = this.prefs.getBoolPref("autosave");
if (this.autosave) HandyTabDataStore.load();
this.markKey = this.prefs.getCharPref("mark.key");
this.invertKey = this.prefs.getCharPref("invert.key");
this.catchLinkClick();
document.addEventListener("HandyTabAddonEvent", function(e) { handytab.onHandyTabAddonEvent(e); }, false, true);
if (this.mobileMode) {
var tabs = document.getElementById("tabs");
tabs.addEventListener("TabSelect", function(e) { handytab.onTabSelect(e); }, false);
} else {
var tabs = gBrowser.tabContainer;
tabs.addEventListener("SSTabRestored", function(e) { handytab.onSSTabRestored(e); }, false);
tabs.addEventListener("TabSelect", function(e) { handytab.onTabSelect(e); }, false);
}
},
onUnload: function() {
if (!this.mobileMode) {
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var enumerator = wm.getEnumerator("navigator:browser");
var count = 0;
while (count < 2 && enumerator.hasMoreElements()) {
var win = enumerator.getNext();
count++;
}
if (count == 2) return;
}
var autosave = this.prefs.getBoolPref("autosave");
if (autosave) HandyTabDataStore.save();
else if (this.autosave) HandyTabDataStore.reset();
},
updateCloseButton: function(tab) {
var showbtn = this.prefs.getBoolPref("show.closebtn");
if (!showbtn) tab.setAttribute("hide-close-button", true);
else if (tab.hasAttribute("hide-close-button")) tab.removeAttribute("hide-close-button");
},
makeHandyTab: function(tab) {
tab.setAttribute("handytab", "true");
tab.setAttribute("flex", 0);
tab.setAttribute("minwidth", 0);
this.updateCloseButton(tab);
var firsttab = this.prefs.getBoolPref("show.firsttab");
if (firsttab && gBrowser.tabContainer.itemCount != 1) gBrowser.moveTabTo(tab, 0);
},
onSSTabRestored: function(e) {
var tab = e.originalTarget;
var ss = Components.classes["@mozilla.org/browser/sessionstore;1"]
.getService(Components.interfaces.nsISessionStore);
var value = ss.getTabValue(tab, "handytab");
if (value) this.makeHandyTab(tab);
},
onTabSelect: function(e) {
this.catchLinkClick();
if (this.mobileMode) {
var tab = Browser.selectedTab;
if (!tab.chromeTab.hasAttribute("handytab")) return;
this.sendMarksToHtml(tab.browser.contentDocument, false);
return;
}
var tab = gBrowser.selectedTab;
if (!tab.hasAttribute("handytab")) return;
var browser = gBrowser.getBrowserForTab(tab);
this.sendMarksToHtml(browser.contentDocument, false);
},
findTabInTabBrowser: function(tabbrowser) {
var numTabs = tabbrowser.browsers.length;
for (var index = 0; index < numTabs; index++) {
var tab = tabbrowser.tabContainer.childNodes[index];
if (tab.hasAttribute("handytab")) return tab;
}
return null;
},
findTab: function(allwin, show) {
if (this.mobileMode) {
for (var i = 0; i < Browser._tabs.length; i++) {
var tab = Browser._tabs[i];
if (tab.chromeTab.hasAttribute("handytab")) {
if (show) Browser.selectedTab = tab;
return tab;
}
}
return null;
}
if (!allwin) {
var tab = this.findTabInTabBrowser(gBrowser);
if (tab && show) gBrowser.selectedTab = tab;
return tab;
}
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var browserEnumerator = wm.getEnumerator("navigator:browser");
while (browserEnumerator.hasMoreElements()) {
var browserWin = browserEnumerator.getNext();
var tabbrowser = browserWin.gBrowser;
var tab = this.findTabInTabBrowser(tabbrowser);
if (tab) {
if (show) {
tabbrowser.selectedTab = tab;
browserWin.focus();
}
return tab;
}
}
return null;
},
showTab: function() {
var tab = this.findTab(true, true);
if (tab) return;
if (this.mobileMode) {
var tab = Browser.addTab(this.homepage, true);
tab.chromeTab.setAttribute("handytab", "true");
return;
}
tab = gBrowser.addTab(this.homepage);
this.makeHandyTab(tab);
var ss = Components.classes["@mozilla.org/browser/sessionstore;1"]
.getService(Components.interfaces.nsISessionStore);
ss.setTabValue(tab, "handytab", true);
gBrowser.selectedTab = tab;
},
// Gather all descendent text under given document node.
gatherTextUnder: function(root)
{
var text = "";
var node = root.firstChild;
var depth = 1;
while ( node && depth > 0 ) {
// See if this node is text.
if ( node.nodeType == Node.TEXT_NODE ) {
// Add this text to our collection.
text += " " + node.data;
} else if ( node instanceof HTMLImageElement) {
// If it has an alt= attribute, use that.
var altText = node.getAttribute( "alt" );
if ( altText && altText != "" ) {
text = altText;
break;
}
}
// Find next node to test.
// First, see if this node has children.
if ( node.hasChildNodes() ) {
// Go to first child.
node = node.firstChild;
depth++;
} else {
// No children, try next sibling.
if ( node.nextSibling ) {
node = node.nextSibling;
} else {
// Last resort is our next oldest uncle/aunt.
node = node.parentNode.nextSibling;
depth--;
}
}
}
// Strip leading whitespace.
text = text.replace( /^\s+/, "" );
// Strip trailing whitespace.
text = text.replace( /\s+$/, "" );
// Compress remaining whitespace.
text = text.replace( /\s+/g, " " );
return text;
},
getLinkText: function(link) {
var text = this.gatherTextUnder(link);
if (!text.match(/\S/)) text = null;
if (!text) {
text = link.getAttribute("title");
if (!text.match(/\S/)) text = null;
if (!text) {
text = link.getAttribute("alt");
if (!text.match(/\S/)) text = null;
}
}
return text;
},
markPage: function() {
var tab = this.mobileMode ? Browser.selectedTab.chromeTab : gBrowser.selectedTab;
var browser = this.mobileMode ? Browser.selectedBrowser : gBrowser.getBrowserForTab(tab);
this.addMark(browser.contentDocument.body);
},
markLink: function(e) {
if (!gContextMenu || !gContextMenu.target) return;
this.addMark(gContextMenu.target);
},
addMark: function(target) {
var url;
var linktext;
if (target.tagName == "A") {
url = target.href;
linktext = this.getLinkText(target);
if (!linktext) linktext = target.href;
} else if (target.tagName == "IMG") {
if (target.parentNode.tagName == "A") {
this.addMark(target.parentNode);
return;
}
url = target.src;
linktext = target.getAttribute("alt");
if (!linktext) linktext = url;
} else if (target.parentNode.tagName == "A") {
this.addMark(target.parentNode);
return;
} else {
url = target.ownerDocument.location.toString();
linktext = target.ownerDocument.title;
}
var refer = target.ownerDocument.location.toString();
var faviconService = Components.classes["@mozilla.org/browser/favicon-service;1"]
.getService(Components.interfaces.nsIFaviconService);
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var icon = "";
var uri = ioService.newURI(refer, null, null);
try {
var faviconURI = faviconService.getFaviconForPage(uri);
icon = faviconURI.spec;
} catch (err) {}
var mark = {linktext: linktext, url: url, refer: refer, icon: icon, time: new Date()};
HandyTabDataStore.addMark(mark);
var notify = this.prefs.getBoolPref("mark.notify");
if (!notify) return;
var alertsService = Components.classes["@mozilla.org/alerts-service;1"]
.getService(Components.interfaces.nsIAlertsService);
alertsService.showAlertNotification("chrome://handytab/skin/handytab.png",
this.strings.getString("extensions.handytab.msg.marked"),
url,
true);
},
toogleMarkMode: function() {
this.markMode = !this.markMode;
if (this.mobileMode) {
var alertsService = Components.classes["@mozilla.org/alerts-service;1"]
.getService(Components.interfaces.nsIAlertsService);
var msg = this.markMode ? this.strings.getString("extensions.handytab.msg.markmode.on") :
this.strings.getString("extensions.handytab.msg.markmode.off");
alertsService.showAlertNotification("chrome://handytab/skin/handytab.png",
msg,
null,
true);
} else {
var statusicon = document.getElementById("handytab-status");
if (this.markMode) statusicon.setAttribute("markmode", true);
else statusicon.removeAttribute("markmode");
}
}
};
window.addEventListener("load", function(e) { handytab.onLoad(e); }, false);
window.addEventListener("unload", function(e) { handytab.onUnload(e); }, false);